﻿using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using RaGE.Properties;

namespace RaGE
{
    public partial class RulesWindow : Form
    {
        public class RuleConfig
        {
            public bool RemoveList;
            public bool ReplaceOffset;
            public string Offset;
            public bool[] RemoveValues;
        }

        public RulesWindow()
        {
            InitializeComponent();
        }

        private void ClickBrowse(object sender, EventArgs e)
        {
            var openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = Resources.ElementsFilter;

            if (openFileDialog.ShowDialog() != DialogResult.OK || !File.Exists(openFileDialog.FileName)) return;

            Cursor = Cursors.AppStarting;
            dataGridView_fields.Rows.Clear();
            dataGridView_values.Rows.Clear();
            comboBox_lists.Items.Clear();

            if (sender == button_browseBase)
            {
                eLC_base = new EListCollection(openFileDialog.FileName);
                textBox_baseFile.Text = openFileDialog.FileName;
                var version = eLC_base.Version;
                textBox_baseVersion.Text = version.ToString(CultureInfo.InvariantCulture);
            }

            if (sender == button_browseRecent)
            {
                eLC_recent = new EListCollection(openFileDialog.FileName);
                textBox_recentFile.Text = openFileDialog.FileName;
                var version2 = eLC_recent.Version;
                textBox_recentVersion.Text = version2.ToString(CultureInfo.InvariantCulture);
            }

            var eListCollection = eLC_base;

            if (eListCollection != null)
            {
                var eListCollection2 = eLC_recent;

                if (eListCollection2 != null && eListCollection.Lists.Length > 0)
                {
                    var num = eListCollection2.Lists.Length;

                    if (num > 0)
                    {
                        eRules = new RuleConfig[num];
                        var num2 = 0;

                        if (0 < eListCollection2.Lists.Length)
                        {
                            do
                            {
                                var eList = eLC_recent.Lists[num2];
                                comboBox_lists.Items.Add("[" + num2 + "]: " + eList.listName + " (" + eList.elementValues.Length + ")");

                                eRules[num2] = new RuleConfig();
                                eRules[num2].RemoveList = false;
                                eRules[num2].ReplaceOffset = false;
                                eRules[num2].Offset = "";
                                eRules[num2].RemoveValues = new bool[eLC_recent.Lists[num2].elementFields.Length];
                                var num3 = 0;

                                if (0 < eRules[num2].RemoveValues.Length)
                                {
                                    do
                                    {
                                        eRules[num2].RemoveValues[num3] = false;
                                        num3++;
                                    }
                                    while (num3 < eRules[num2].RemoveValues.Length);
                                }
                                num2++;
                            }
                            while (num2 < eLC_recent.Lists.Length);
                        }
                    }
                }
            }
            Cursor = Cursors.Default;
        }

        private int CountMismatches(int listIndex, int baseFieldIndex, int recentFieldIndex)
        {
            if (baseFieldIndex >= eLC_base.Lists[listIndex].elementFields.Length)
                return eLC_recent.Lists[listIndex].elementValues.Length;

            if (recentFieldIndex >= eLC_recent.Lists[listIndex].elementFields.Length)
                return eLC_base.Lists[listIndex].elementValues.Length;

            return eLC_recent.Lists[listIndex].elementValues.TakeWhile((t, e) => e <
                eLC_base.Lists[listIndex].elementValues.Length && e <
                eLC_recent.Lists[listIndex].elementValues.Length).Where((t, e) => eLC_base.GetValue(listIndex, e, baseFieldIndex) !=
                    eLC_recent.GetValue(listIndex, e, recentFieldIndex)).Count();
        }

        private void ChangeList(object sender, EventArgs e)
        {
            Cursor = Cursors.AppStarting;

            dataGridView_fields.Rows.Clear();
            dataGridView_values.Rows.Clear();

            var list = comboBox_lists.SelectedIndex;

            if (list > -1)
            {
                if (eLC_base.Lists.Length > list && eLC_base.ConversationListIndex != list)
                {
                    var baseFieldIndex = 0;
                    var recentFieldIndex = 0;

                    checkBox_removeList.Checked = eRules[list].RemoveList;

                    if (eRules[list].ReplaceOffset)
                    {
                        radioButton_baseOffset.Checked = true;
                        radioButton_recentOffset.Checked = false;
                    }
                    else
                    {
                        radioButton_baseOffset.Checked = false;
                        radioButton_recentOffset.Checked = true;
                    }

                    textBox_baseOffset.Text = eLC_base.GetOffset(list);
                    textBox_recentOffset.Text = eLC_recent.GetOffset(list);

                    for (var i = 0; i < eLC_recent.Lists[list].elementFields.Length; i++)
                    {
                        if (eRules[list].RemoveValues[i] || baseFieldIndex >= eLC_base.Lists[list].elementFields.Length)
                        {
                            baseFieldIndex--;
                            dataGridView_fields.Rows.Add(new object[]
                            {
                                "", eLC_recent.Lists[list].elementTypes[recentFieldIndex],
                                CountMismatches(list, baseFieldIndex, recentFieldIndex).ToString(CultureInfo.InvariantCulture),
                                eRules[list].RemoveValues[i].ToString(), "Details"
                            });
                        }
                        else
                        {
                            dataGridView_fields.Rows.Add(new object[]
                            {
                                eLC_base.Lists[list].elementTypes[baseFieldIndex],
                                eLC_recent.Lists[list].elementTypes[recentFieldIndex],
                                CountMismatches(list, baseFieldIndex, recentFieldIndex).ToString(CultureInfo.InvariantCulture),
                                eRules[list].RemoveValues[i].ToString(), "Details"
                            });
                        }
                        
                        dataGridView_fields.Rows[dataGridView_fields.Rows.Count - 1].HeaderCell.Value = i.ToString(CultureInfo.InvariantCulture);
                        baseFieldIndex++;
                        recentFieldIndex++;
                    }
                }
            }
            Cursor = Cursors.Default;
        }

        private void ClickField(object sender, DataGridViewCellEventArgs e)
        {
            var l = comboBox_lists.SelectedIndex;

            if (l > -1 && e.ColumnIndex == 3 && e.RowIndex > -1)
            {
                var displayRow = dataGridView_fields.FirstDisplayedCell.RowIndex;
                var displayCol = dataGridView_fields.FirstDisplayedCell.ColumnIndex;

                // click event don't has new state, we need to access next state property: EditedFormattedValue
                eRules[l].RemoveValues[e.RowIndex] = Convert.ToBoolean(dataGridView_fields.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue);
                ChangeList(null, null);
                dataGridView_fields.FirstDisplayedCell = dataGridView_fields.Rows[displayRow].Cells[displayCol];
            }

            if (l <= -1 || e.ColumnIndex != 4 || e.RowIndex <= -1) return;

            Cursor = Cursors.AppStarting;
            dataGridView_values.Rows.Clear();

            var baseFieldIndex = 0;
            var recentFieldIndex = 0;

            for (var i = 0; i < e.RowIndex; i++)
            {
                if (eRules[l].RemoveValues[i])
                    baseFieldIndex--;

                baseFieldIndex++;
                recentFieldIndex++;
            }

            if (baseFieldIndex < eLC_base.Lists[l].elementFields.Length && recentFieldIndex < eLC_recent.Lists[l].elementFields.Length)
            {
                //array<DataGridViewRow^>^ rows;

                for (var i = 0; i < eLC_recent.Lists[l].elementValues.Length; i++)
                {
                    dataGridView_values.Rows.Add(i < eLC_base.Lists[l].elementValues.Length ? new object[]
                    {
                        eLC_base.GetValue(l, i, baseFieldIndex),
                        eLC_recent.GetValue(l, i, recentFieldIndex)
                    }
                    : new object[] { "", eLC_recent.GetValue(l, i, recentFieldIndex) });

                    dataGridView_values.Rows[dataGridView_values.Rows.Count - 1].HeaderCell.Value =
                        i.ToString(CultureInfo.InvariantCulture);
                }

                //dataGridView_values->Rows->AddRange(rows);
            }
            Cursor = Cursors.Default;
        }
    }


}

